<template>
	<view class="picture-tailor" :class="{ 'picture-tailor-show': isShow }">
			<movable-area class="picture-area">
				<movable-view
					class="picture-view"
					:style="{ width: img_width / img_scaling + 'px', height: img_height / img_scaling + 'px' }"
					direction="all"
					:x="offsetX"
					:y="offsetY"
					scale="true"
					:scale-min="scaleMin"
					@change="movableChange"
					@scale="movableScale">
					<image :style="{ width: img_width / img_scaling + 'px', height: img_height / img_scaling + 'px' }" :src="pictureSrc"></image>
				</movable-view>
			</movable-area>
		<view class="select-box"></view>
		<view class="buts" style="background-color: black;">
			<button class="button-no" @click="hide">取消</button>
			<button class="button-ok" @click="createImg">确定</button>
		</view>
		<canvas type="2d" id="picture-canvas" class="canvas-view"></canvas>
	</view>
</template>

<script>
	// rpx转px
	function rpxToPx(rpx) {
		const screenWidth = uni.getSystemInfoSync().screenWidth
		return (screenWidth * Number.parseInt(rpx)) / 750
	}
	
	// 480rpx 转px
	let tailorSize = rpxToPx(480); // 需要截取的尺寸480rpx x 480rpx，此变量要和样式中的480rpx和240rpx相对应，240rpx为此变量的一半，若要修改成其他值一定要一一对应
	let newOffsetX = 0; // 拖动缩放完成后的X轴偏移量
	let newOffsetY = 0; // 拖动缩放完成后的Y轴偏移量

	export default {
		name: "lv-clip",
		data() {
			return {
				pictureSrc:'',// 图片
				offsetX: 0, // 图像初始化的X轴偏移量
				offsetY: 0, // 图像初始化的Y轴偏移量
				img_width: 0, // 图片真实宽度
				img_height: 0, // 图片真实高度
				img_scaling: 1, //图片初始化缩放比例
				scale: 1, // 拖动缩放完成后的图片缩放比例
				scaleMin: 0.5, // 最小缩放值
				isShow: false
			};
		},
		methods: {
			// 显示组件
			show(img) {
				this.pictureSrc = img; // 赋值图片
				this.getImgInfo(); // 初始化图片
				this.isShow = true; // 显示组件
			},
			// 隐藏组件
			hide() {
				this.isShow = false;
			},
			// 初始化图片
			getImgInfo() {
				uni.getImageInfo({
					src: this.pictureSrc,
					success: res => {
						// 图片宽高
						this.img_width = res.width;
						this.img_height = res.height;

						// 把最小的边撑满
						let count = this.img_width <= this.img_height ? this.img_width : this.img_height;
						this.img_scaling = count / tailorSize;
						this.scaleMin = 1;

						// 计算图片居中显示时的偏移量
						this.offsetX = -(this.img_width / this.img_scaling / 2 - tailorSize / 2);
						this.offsetY = -(this.img_height / this.img_scaling / 2 - tailorSize / 2);

						// 获取新的偏移量
						newOffsetX = this.offsetX;
						newOffsetY = this.offsetY;
					}
				});
			},
			// 计算拖动偏移量
			movableChange(e) {
				newOffsetX = e.detail.x;
				newOffsetY = e.detail.y;
			},
			// 计算缩放比例和偏移量
			movableScale(e) {
				newOffsetX = e.detail.x;
				newOffsetY = e.detail.y;
				this.scale = e.detail.scale;
			},
			// 截取图片
			createImg() {
				
				// #ifdef MP-WEIXIN
				uni.createSelectorQuery().in(this).select('#picture-canvas').fields({ node: true, size: true })
					.exec((res) => {
						const canvas = res[0].node;
						canvas.width = tailorSize;
						canvas.height = tailorSize;
						
						const ctx = canvas.getContext('2d')
						
						let headerImg = canvas.createImage();	//创建iamge实例
						headerImg.src = this.pictureSrc;	//临时图片路径
						headerImg.onload = () => {
							ctx.drawImage(
								headerImg,
								newOffsetX,//起点 X 坐标
								newOffsetY,//起点 Y 坐标
								(this.img_width / this.img_scaling) * this.scale,//终点 X 坐标
								(this.img_height / this.img_scaling) * this.scale//终点 Y 坐标
							);
							ctx.restore();	//保存上下文	
							uni.canvasToTempFilePath({
								quality: 1,// 图片质量0-1
								canvas:canvas,
								fileType: 'png',
								success: res => {
									// 在H5平台下，tempFilePath 为 base64
									this.hide(); // 关闭
									this.$emit("createImg", res.tempFilePath);
								},
								fail: function (res) {
									this.hide(); // 关闭
								}
							},this);
						};
					})
				// #endif
				
				
				// #ifdef MP-DINGTALK
				let ctx = uni.createCanvasContext("picture-canvas", this);
				ctx.drawImage(
					this.pictureSrc,
					newOffsetX,//起点 X 坐标
					newOffsetY,//起点 Y 坐标
					(this.img_width / this.img_scaling) * this.scale,//终点 X 坐标
					(this.img_height / this.img_scaling) * this.scale//终点 Y 坐标
				);
				ctx.draw(false, () => {
					uni.canvasToTempFilePath(
						{
							quality: 1,// 图片质量0-1
							canvasId: "picture-canvas",// 画布标识，传入 <canvas/> 的 canvas-id（支付宝小程序是id、其他平台是canvas-id）
							success: res => {
								this.hide(); // 关闭
								this.$emit("createImg", res.tempFilePath);
							},
							fail: function (res) {
								this.hide(); // 关闭
							}
						},
						this
					);
				});
				// #endif
				
				
			}
		}
	};
</script>

<style scoped>
	.picture-tailor {
		position: fixed;
		z-index:999;
		top: 0;
		left: 0;
		bottom: 0;
		right: 0;
		width: 100%;
		height: 100%;
		background-color: #6B6B6B;
		transform: translateX(100%);
		transition: all 200ms ease;
		overflow: hidden;
		visibility: hidden;
	}

	.picture-tailor-show {
		transform: translateY(0) !important;
		visibility: visible;
	}

	/* 拖动域的位置和大小 */
	.picture-tailor .picture-area {
		width: 480rpx;
		height: 480rpx;
		position: absolute;
		/* 使其居中定位 */
		top: calc(50% - 240rpx);
		left: calc(50% - 240rpx);
		   /* overflow: hidden;
		    border-radius: 50%; */
	}

	/* 拖动控件的大小 */
	.picture-area .picture-view {
		min-width: 480rpx;
		min-height: 480rpx;
	}

	/* 中间选择框的大小，本意是视觉上模拟拖动域 */
	.select-box {
		position: absolute;
		top: calc(50% - 240rpx);
		left: calc(50% - 240rpx);
		width: 480rpx;
		height: 480rpx;
		box-sizing: border-box;
		border-radius: 50%;
		border: #ffffff 1rpx solid;
		pointer-events: none;
	}
.buts{
	width: 100vw;
	height: 128rpx;
	align-items: center;
	position: absolute;
	/* padding: 0 32rpx; */
	bottom: 0rpx;
	display: flex;
	/* justify-content: space-between; */
	background-color: #000000;
}
	.button-ok {
		
		width: 120rpx;
		background-color: #007aff;
		font-size: 28rpx;
		color: #ffffff;
		margin-right: 64rpx;
	}
	.button-no {
		width: 120rpx;
		background-color: #000000;
		font-size: 28rpx;
		color: #ffffff;
	margin-left: 64rpx;
	}

	/* 画布大小，画布大小就是截取的原始大小 */
	.canvas-view {
		width: 480rpx;
		height: 480rpx;
		position: relative;
		z-index:999;
		left: -9999rpx;
		visibility: hidden;
	}
</style>
